import fetch from 'node-fetch';
import path from 'path';
import fs from 'fs/promises';
import { ExtensionApiMap } from './types';
import { ReflectionKind } from 'typedoc';

// Bucket used to store processed types data
const STORAGE_BUCKET = process.env.STORAGE_BUCKET;

// Fetch the latest version of the chrome types from storage
const fetchChromeTypes = async (): Promise<Record<string, any>> => {
  if (!STORAGE_BUCKET) {
    throw new Error('The STORAGE_BUCKET environment variable must be set.');
  }

  console.log('Fetching chrome types...');

  const response = await fetch(
    `https://storage.googleapis.com/download/storage/v1/b/${STORAGE_BUCKET}/o/chrome-types.json?alt=media`
  );
  const chromeTypes = await response.json();
  return chromeTypes;
};

const run = async () => {
  const result: ExtensionApiMap = {};

  const chromeTypes = await fetchChromeTypes();

  for (const [chromeApiKey, chromeApiDetails] of Object.entries(chromeTypes)) {
    const apiDetails: ExtensionApiMap[string] = {
      properties: [],
      methods: [],
      types: [],
      events: []
    };

    for (let property of chromeApiDetails._type.properties) {
      const name = property.name as string;

      // check property type
      let propertyType = 'types';
      if (property.kind & ReflectionKind.VariableOrProperty) {
        propertyType = 'properties';
      }
      if (
        property.type?.type === 'reference' &&
        ['CustomChromeEvent', 'events.Event', 'Event'].includes(
          property.type.name
        )
      ) {
        propertyType = 'events';
      }
      if (property.signatures) {
        propertyType = 'methods';
      }

      apiDetails[propertyType].push(name);
    }

    result[chromeApiKey] = apiDetails;
  }

  console.log('Writing to file...');
  await fs.writeFile(
    path.join(__dirname, '../extension-apis.json'),
    JSON.stringify(
      {
        _comment:
          'This file is autogenerated by running `npm run prepare-chrome-types`, do not edit.',
        ...result
      },
      null,
      2
    )
  );
  console.log('Done!');
};

run();
